package com.youshang520i.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 描述信息
 *
 * @author hardy
 * @date 2021/3/3 14:49
 */
public class PrintDemo {


    public static void main(String[] args) {
        new Thread(new PrintTask2(3)).start();
        new Thread(new PrintTask2(2)).start();
        new Thread(new PrintTask2(1)).start();
    }

    static class PrintTask implements Runnable {

        private final int threadNum;
        private static volatile int i = 1;
        private static final Object LOCK_OBJ = new Object();

        PrintTask(int threadNum) {
            this.threadNum = threadNum;
        }

        @Override
        public void run() {
            while (i < 99) {
                // 第一个线程 只能打印 1 4 7
                if (threadNum % 3 == 1) {
                    synchronized (LOCK_OBJ) {
                        while (i % 3 != 1) {
                            try {
                                LOCK_OBJ.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        print(threadNum);
                        LOCK_OBJ.notifyAll();
                    }
                }
                if (threadNum % 3 == 2) {
                    synchronized (LOCK_OBJ) {
                        while (i % 3 != 2) {
                            try {
                                LOCK_OBJ.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        print(threadNum);
                        LOCK_OBJ.notifyAll();

                    }
                }
                if (threadNum % 3 == 0) {
                    synchronized (LOCK_OBJ) {
                        while (i % 3 != 0) {
                            try {
                                LOCK_OBJ.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        print(threadNum);
                        LOCK_OBJ.notifyAll();
                    }
                }
            }
        }

        public void print(int threadNum) {
            System.out.println("Thread-" + threadNum + ":" + (i++));
        }
    }


    static class PrintTask2 implements Runnable {

        private final int threadNum;
        private static volatile int i = 1;
        private static final ReentrantLock lock = new ReentrantLock();
        private static final Condition condition1 = lock.newCondition();
        private static final Condition condition2 = lock.newCondition();
        private static final Condition condition3 = lock.newCondition();

        PrintTask2(int threadNum) {
            this.threadNum = threadNum;
        }

        @Override
        public void run() {
            // 第一个线程 只能打印 1 4 7
            if (threadNum % 3 == 1) {
                while (i < 99) {
                    try {
                        lock.lock();
                        while (i % 3 != 1) {
                            condition1.await();
                        }
                        print(threadNum);
                        condition2.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            }
            if (threadNum % 3 == 2) {
                while (i < 99) {
                    try {
                        lock.lock();
                        while (i % 3 != 2) {
                            condition2.await();
                        }
                        print(threadNum);
                        condition3.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }

            }
            if (threadNum % 3 == 0) {
                while (i < 99) {
                    try {
                        lock.lock();
                        while (i % 3 != 0) {
                            condition3.await();
                        }
                        print(threadNum);
                        condition1.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }

        public void print(int threadNum) {
            System.out.println("Thread-" + threadNum + ":" + (i++));
        }
    }


}